package com.ruoyi.combat.service.equiplocation.impl;

import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.ruoyi.combat.domain.equiplocation.CombatEquipInfo;
import com.ruoyi.combat.domain.equiplocation.CombatEquipRepositingTask;
import com.ruoyi.combat.domain.equiplocation.CombatEquipTask;
import com.ruoyi.combat.domain.equiplocation.CombatFakeIp;
import com.ruoyi.combat.domain.position.AntiPositioningInfo;
import com.ruoyi.combat.domain.request.AntiAttributionCallbackRequest;
import com.ruoyi.combat.domain.vo.RiskDataStatisticsVo;
import com.ruoyi.combat.mapper.equiplocation.CombatEquipInfoMapper;
import com.ruoyi.combat.mapper.equiplocation.CombatEquipRepositingTaskMapper;
import com.ruoyi.combat.mapper.equiplocation.CombatEquipTaskMapper;
import com.ruoyi.combat.mapper.equiplocation.CombatFakeIpMapper;
import com.ruoyi.combat.service.equiplocation.ICombatEquipInfoRepositingTaskService;
import com.ruoyi.combat.service.equiplocation.ICombatEquipInfoService;
import com.ruoyi.combat.service.externalServiceInvoker.AntiPositioningService;
import com.ruoyi.combat.service.externalServiceInvoker.PinpointService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import org.checkerframework.checker.units.qual.A;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 网络IPService业务层处理
 *
 * @author ruoyi
 * @date 2025-01-06
 */
@Service
public class CombatEquipInfoServiceImpl implements ICombatEquipInfoService
{
    private static final Logger log = LoggerFactory.getLogger(CombatEquipInfoServiceImpl.class);

    @Autowired
    private CombatEquipInfoMapper combatEquipInfoMapper;
    @Autowired
    private CombatEquipTaskMapper combatEquipTaskMapper;
    @Autowired
    private CombatFakeIpMapper combatFakeIpMapper;
    @Autowired
    private PinpointService pinpointService;
    @Autowired
    private CombatEquipRepositingTaskMapper combatEquipRepositingTaskMapper;
    @Autowired
    private AntiPositioningService antiPositioningService;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    @Autowired
    private ICombatEquipInfoRepositingTaskService combatEquipInfoRepositingTaskService;



    /**
     * 查询网络IP
     *
     * @param id 网络IP主键
     * @return 网络IP
     */
    @Override
    public CombatEquipInfo selectCombatEquipInfoById(Long id)
    {
        return combatEquipInfoMapper.selectCombatEquipInfoById(id);
    }

    /**
     * 查询网络IP列表
     *
     * @param combatEquipInfo 网络IP
     * @return 网络IP
     */
    @Override
    public List<CombatEquipInfo> selectCombatEquipInfoList(CombatEquipInfo combatEquipInfo)
    {
        return combatEquipInfoMapper.selectCombatEquipInfoList(combatEquipInfo);
    }

    /**
     * 新增网络IP
     *
     * @param combatEquipInfo 网络IP
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCombatEquipInfo(CombatEquipInfo combatEquipInfo)
    {
        // 校验参数是否为空
        if (ObjectUtil.isNull(combatEquipInfo)){
            log.error("参数为空");
            throw new BaseException("参数为空");
        }
        if (StrUtil.isBlank(combatEquipInfo.getEquipIp())
                || StrUtil.isBlank(combatEquipInfo.getEquipCity())
                || StrUtil.isBlank(combatEquipInfo.getEquipLat())
                || StrUtil.isBlank(combatEquipInfo.getEquipLon())){
            log.error("参数为空");
            throw new BaseException("参数为空");
        }
        // 查询当前设备是否已存在
        CombatEquipInfo info = combatEquipInfoMapper.selectCombatEquipInfoByIp(combatEquipInfo.getEquipIp());
        if (ObjectUtil.isNotNull(info)){
            log.error("设备已存在");
            throw new BaseException("设备已存在");
        }
        // 获取定位算法标识
        if (StrUtil.isBlank(combatEquipInfo.getAlgorithmMark())){
            log.error("参数为空");
            throw new BaseException("参数为空");
        }
        combatEquipInfo.setRiskMark("1");
        Map<String,Object> map = new HashMap<>(16);
        if ("1".equals(combatEquipInfo.getAlgorithmMark())){
            // 定位
            map = pinpointService.pinpoint(combatEquipInfo.getEquipIp(), combatEquipInfo.getEquipCity(), combatEquipInfo.getEquipLon(), combatEquipInfo.getEquipLat());
            combatEquipInfo.setBeforeEquipRiskLat(map.get("geo_lat").toString());
            combatEquipInfo.setBeforeEquipRiskLon(map.get("geo_lon").toString());
            String error = map.get("error").toString();
            // 保留两位小数
            combatEquipInfo.setBeforeRiskDistance(new DecimalFormat("#.00").format(Double.parseDouble(error)));
            // 判断设备风险等级，如果风险距离大于等于10小于30，则为中风险，大于30则为低风险，小于10则为高风险
            if (Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) >= 10 && Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) < 30){
                combatEquipInfo.setRiskLevel("2");
            }else if (Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) < 10){
                combatEquipInfo.setRiskLevel("3");
            }else {
                combatEquipInfo.setRiskLevel("1");
            }
        } else if ("2".equals(combatEquipInfo.getAlgorithmMark())){
            // 新增基于时延的定位任务
            CombatEquipRepositingTask combatEquipRepositingTask = new CombatEquipRepositingTask();
            combatEquipRepositingTask.setProtectedIp(combatEquipInfo.getEquipIp());
            combatEquipRepositingTask.setStartime(new Date());
            combatEquipRepositingTask.setTaskState("1");
            combatEquipRepositingTask.setEquipLat(combatEquipInfo.getEquipLat());
            combatEquipRepositingTask.setEquipLon(combatEquipInfo.getEquipLon());
            combatEquipRepositingTaskMapper.insertCombatEquipRepositingTask(combatEquipRepositingTask);
            // 定位
            pinpointService.pinpointDelay(combatEquipRepositingTask.getId(), combatEquipInfo.getEquipIp(), combatEquipInfo.getEquipCity(), combatEquipInfo.getEquipLon(), combatEquipInfo.getEquipLat());
        } else {
            log.error("参数错误");
            throw new BaseException("参数错误");
        }
//        combatEquipInfo.setRiskLevel("2");
//        combatEquipInfo.setBeforeEquipRiskLat("31.186602");
//        combatEquipInfo.setBeforeEquipRiskLon("121.282658");
//        combatEquipInfo.setBeforeRiskDistance("20");
//        combatEquipInfo.setRiskMark("1");
        return combatEquipInfoMapper.insertCombatEquipInfo(combatEquipInfo);
    }

    /**
     * 修改网络IP
     *
     * @param combatEquipInfo 网络IP
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCombatEquipInfo(CombatEquipInfo combatEquipInfo)
    {
        return combatEquipInfoMapper.updateCombatEquipInfo(combatEquipInfo);
    }

    /**
     * 批量删除网络IP
     *
     * @param ids 需要删除的网络IP主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteCombatEquipInfoByIds(Long[] ids)
    {
        return combatEquipInfoMapper.deleteCombatEquipInfoByIds(ids);
    }

    /**
     * 删除网络IP信息
     *
     * @param id 网络IP主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteCombatEquipInfoById(Long id)
    {
        return combatEquipInfoMapper.deleteCombatEquipInfoById(id);
    }

    /**
     * 执行基于虚假地标的抗定位操作
     * 该方法旨在通过引入虚假IP地址来保护真实目标IP地址的隐私，提高位置数据的安全性
     *
     * @param antiPositioningInfo 请求参数对象，包含目标IP地址和一系列虚假IP地址
     *                            这些信息用于执行抗定位操作，以保护真实位置信息
     */
    @Override
    public void antiPositioning(AntiPositioningInfo antiPositioningInfo) {
        if (antiPositioningInfo == null){
            log.error("请求参数对象为空");
            throw new BaseException("请求参数对象为空");
        }
        // 判断参数不为空
        if (StrUtil.isBlank(antiPositioningInfo.getTargetIP())
                || antiPositioningInfo.getClIPList().size() <= 0){
            log.error("请求参数为空");
            throw new BaseException("请求参数为空");
        }
        // 根据目标IP查询设备信息
        CombatEquipInfo combatEquipInfo = combatEquipInfoMapper.selectCombatEquipInfoByIp(antiPositioningInfo.getTargetIP());
        if (combatEquipInfo == null){
            log.error("设备不存在");
            throw new BaseException("设备不存在");
        }
        antiPositioningInfo.setCityName(combatEquipInfo.getEquipCity());
        antiPositioningInfo.setLon(combatEquipInfo.getEquipLon());
        antiPositioningInfo.setLat(combatEquipInfo.getEquipLat());
        // 往抗定位任务里插入一条数据
        CombatEquipTask combatEquipTask = new CombatEquipTask();
        combatEquipTask.setTaskMethod("1");
        combatEquipTask.setTaskState("1");
        combatEquipTask.setStartime(DateUtil.date());
        combatEquipTask.setProtectedIp(antiPositioningInfo.getTargetIP());
        String beforeRiskDistance = combatEquipInfo.getBeforeRiskDistance();
        // 保留两位小数
        combatEquipTask.setBeforeRiskDistance(new DecimalFormat("#.00").format(Double.parseDouble(beforeRiskDistance)));
        combatEquipTask.setRiskLevel(combatEquipInfo.getRiskLevel());
        combatEquipTaskMapper.insertCombatEquipTask(combatEquipTask);
        Long id = combatEquipTask.getId();
        antiPositioningService.antiPositioning(antiPositioningInfo.getTargetIP(), antiPositioningInfo.getClIPList(), antiPositioningInfo.getCityName(), antiPositioningInfo.getLon(), antiPositioningInfo.getLat(), id);
    }

    /**
     * 通过延迟时间进行抗定位操作
     *
     * 当接收到抗定位请求时，该方法会根据提供的目标IP和延迟时间来执行反定位操作
     * 如果请求参数对象为空，或者目标IP和延迟时间中的任何一个为空，则会抛出异常
     *
     * @param antiPositioningInfo 包含目标IP和延迟时间的反定位信息对象
     * @throws BaseException 如果请求参数对象为空，或者目标IP和延迟时间中的任何一个为空，则抛出此异常
     */
    @Override
    public void antiPositioningByDelay(AntiPositioningInfo antiPositioningInfo) {
        if (antiPositioningInfo == null){
            log.error("请求参数对象为空");
            throw new BaseException("请求参数对象为空");
        }
        // 判断参数不为空
        if (StrUtil.isBlank(antiPositioningInfo.getTargetIP())
                || ObjectUtil.isNull(antiPositioningInfo.getDelayTime())){
            log.error("请求参数为空为空");
            throw new BaseException("请求参数为空为空");
        }
        // 根据目标IP查询设备信息
        CombatEquipInfo combatEquipInfo = combatEquipInfoMapper.selectCombatEquipInfoByIp(antiPositioningInfo.getTargetIP());
        if (combatEquipInfo == null){
            log.error("设备不存在");
            throw new BaseException("设备不存在");
        }
        antiPositioningInfo.setCityName(combatEquipInfo.getEquipCity());
        antiPositioningInfo.setLon(combatEquipInfo.getEquipLon());
        antiPositioningInfo.setLat(combatEquipInfo.getEquipLat());
        if (antiPositioningInfo.getDelayTime() <= 0){
            log.error("延迟时间必须大于0");
            throw new BaseException("延迟时间必须大于0");
        }
        // 往抗定位任务里插入一条数据
        CombatEquipTask combatEquipTask = new CombatEquipTask();
        combatEquipTask.setTaskMethod("2");
        combatEquipTask.setTaskState("1");
        combatEquipTask.setStartime(DateUtil.date());
        String beforeRiskDistance = combatEquipInfo.getBeforeRiskDistance();
        // beforeRiskDistance 保留两位小数
        combatEquipTask.setBeforeRiskDistance(new DecimalFormat("#.00").format(Double.parseDouble(beforeRiskDistance)));
        combatEquipTask.setRiskLevel(combatEquipInfo.getRiskLevel());
        combatEquipTask.setProtectedIp(antiPositioningInfo.getTargetIP());
        combatEquipTaskMapper.insertCombatEquipTask(combatEquipTask);
        Long id = combatEquipTask.getId();

        SysConfig sysConfig = sysConfigMapper.selectConfigById(7L);
        if("true".equals(sysConfig.getConfigValue())) {
            antiPositioningService.antiPositioningByDelay(antiPositioningInfo.getTargetIP(), antiPositioningInfo.getDelayTime(), antiPositioningInfo.getCityName(), antiPositioningInfo.getLon(), antiPositioningInfo.getLat(), id);

            // 抗定位已完成，修改设备状态为抗定位已完成
            combatEquipInfo.setRiskMark("2");
            combatEquipInfoMapper.updateCombatEquipInfo(combatEquipInfo);

            // 修改任务状态为已完成
//            combatEquipTask.setTaskState("2");
//            combatEquipTaskMapper.updateCombatEquipTask(combatEquipTask);

            // 基于网关的抗定位成功。生成基于时延的重定位任务
            // 新增基于时延的定位任务
            CombatEquipRepositingTask combatEquipRepositingTask = new CombatEquipRepositingTask();
            combatEquipRepositingTask.setProtectedIp(combatEquipInfo.getEquipIp());
            combatEquipRepositingTask.setStartime(new Date());
            combatEquipRepositingTask.setTaskState("1");
            combatEquipRepositingTask.setEquipLat(combatEquipInfo.getEquipLat());
            combatEquipRepositingTask.setEquipLon(combatEquipInfo.getEquipLon());
            combatEquipRepositingTaskMapper.insertCombatEquipRepositingTask(combatEquipRepositingTask);
            //调用延时定位
            pinpointService.pinpointDelay(combatEquipRepositingTask.getId(), antiPositioningInfo.getTargetIP(), antiPositioningInfo.getCityName(), antiPositioningInfo.getLon(), antiPositioningInfo.getLat());
        } else {
            // 模拟抗定位成功
//            try {
//                Thread.sleep(1000);
//            } catch (Exception e) {
//                log.error("线程休眠异常:" + e.getMessage(), e);
//            }

            // 抗定位已完成，修改设备状态为抗定位已完成
            combatEquipInfo.setRiskMark("2");
            combatEquipInfoMapper.updateCombatEquipInfo(combatEquipInfo);

            // 修改任务状态为已完成
//            combatEquipTask.setTaskState("2");
//            combatEquipTaskMapper.updateCombatEquipTask(combatEquipTask);

            // 新增基于时延的定位任务
            CombatEquipRepositingTask combatEquipRepositingTask = new CombatEquipRepositingTask();
            combatEquipRepositingTask.setProtectedIp(combatEquipInfo.getEquipIp());
            combatEquipRepositingTask.setStartime(new Date());
            combatEquipRepositingTask.setTaskState("1");
            combatEquipRepositingTask.setEquipLat(combatEquipInfo.getEquipLat());
            combatEquipRepositingTask.setEquipLon(combatEquipInfo.getEquipLon());
            combatEquipRepositingTask.setBeforeDistance(combatEquipInfo.getBeforeRiskDistance());
            combatEquipRepositingTaskMapper.insertCombatEquipRepositingTask(combatEquipRepositingTask);

            // 根据当前经度和纬度，计算风险距离大于30KM的经纬度
            String afterEquipRiskLat = "";
            String afterEquipRiskLon = "";
            afterEquipRiskLat = "" + (Double.parseDouble(combatEquipInfo.getEquipLat()) + 1);
            afterEquipRiskLon = "" + (Double.parseDouble(combatEquipInfo.getEquipLon()) + 1);
            // 创建 Random 对象
            Random random = new Random();
            // 生成一个大于 30 且小于 130 的随机数
            double randomNumber = 30 + random.nextDouble() * 100;
            // 创建 DecimalFormat 对象，用于格式化输出，保留五位小数
            DecimalFormat df = new DecimalFormat("#.00000");
            // 格式化随机数
            String formattedNumber = df.format(randomNumber);
            Double afterRiskDistance = Double.parseDouble(formattedNumber);
            // 调用回调
            CombatEquipRepositingTask task = new CombatEquipRepositingTask();
            task.setId(combatEquipRepositingTask.getId());
            task.setAfterLat(afterEquipRiskLat);
            task.setAfterLon(afterEquipRiskLon);
            task.setAfterDistance(afterRiskDistance.toString());
            combatEquipInfoRepositingTaskService.callback(task);
        }
    }

    /**
     * 设备风险数据统计
     * 此方法用于统计设备的风险数据，将设备按风险等级分为低、中、高三个级别，并计算每个级别的设备数量
     * @return RiskDataStatisticsVo 返回一个包含各风险级别设备数量的对象，如果没有任何设备信息，则返回null
     */
    @Override
    public RiskDataStatisticsVo riskDataStatistics() {
        // 获取所有设备信息
        List<CombatEquipInfo> equipInfoList = combatEquipInfoMapper.selectCombatEquipInfoList(new CombatEquipInfo());
        if (equipInfoList == null || equipInfoList.isEmpty()) {
            return null;
        }

        RiskDataStatisticsVo vo = new RiskDataStatisticsVo();
        int lowRiskCount = 0;
        int mediumRiskCount = 0;
        int highRiskCount = 0;

        for (CombatEquipInfo equipInfo : equipInfoList) {
            String riskLevel = equipInfo.getRiskLevel();
            if ("1".equals(riskLevel)) {
                lowRiskCount++;
            } else if ("2".equals(riskLevel)) {
                mediumRiskCount++;
            } else if ("3".equals(riskLevel)) {
                highRiskCount++;
            }
        }

        vo.setLowRiskCount(lowRiskCount);
        vo.setMediumRiskCount(mediumRiskCount);
        vo.setHighRiskCount(highRiskCount);
        return vo;
    }

    /**
     * 抗定位后回调方法
     * @param request
     */
    @Override
    @Transactional
    public AjaxResult antiAttributionCallback(AntiAttributionCallbackRequest request) {
        Long taskId = request.getTaskId();
        // 根据任务Id查询抗定位任务
        CombatEquipTask combatEquipTask = combatEquipTaskMapper.selectCombatEquipTaskById(taskId);
        if (combatEquipTask == null) {
            log.error("未查询到对应抗定位任务");
            return AjaxResult.error("未查询到对应抗定位任务");
        }
        // 修改抗定位任务状态为已完成
        combatEquipTask.setTaskState("2");
        combatEquipTask.setEndtime(DateUtil.date());
        combatEquipTask.setAfterEquipRiskLat(request.getAfterEquipRiskLat());
        combatEquipTask.setAfterEquipRiskLon(request.getAfterEquipRiskLon());
        String afterRiskDistance = request.getAfterRiskDistance();
        // afterRiskDistance保留两位小数
        afterRiskDistance = NumberUtil.decimalFormat("0.00", Double.parseDouble(afterRiskDistance));
        combatEquipTask.setAfterRiskDistance(afterRiskDistance);

        // 根据目标IP 查询设备信息
        CombatEquipInfo combatEquipInfo = combatEquipInfoMapper.selectCombatEquipInfoByIp(combatEquipTask.getProtectedIp());
        if (combatEquipInfo == null) {
            log.error("未查询到对应设备信息");
            return AjaxResult.error("未查询到对应设备信息");
        }
        combatEquipTask.setBeforeRiskDistance(combatEquipInfo.getBeforeRiskDistance());
        combatEquipTaskMapper.updateCombatEquipTask(combatEquipTask);

        combatEquipInfo.setRiskMark("2");
        combatEquipInfo.setAfterEquipRiskLat(request.getAfterEquipRiskLat());
        combatEquipInfo.setAfterEquipRiskLon(request.getAfterEquipRiskLon());

        combatEquipInfo.setAfterRiskDistance(afterRiskDistance);
        combatEquipInfo.setEquipEstime(request.getEquipEstime());
        combatEquipInfo.setUpdateTime(new Date());
        // 抗定位后风险等级0-10为高风险，10-30为中风险，30以上为低风险
        if (StrUtil.isNotBlank(request.getAfterRiskDistance())) {
            double riskDistance = Double.parseDouble(request.getAfterRiskDistance());
            if (riskDistance <= 10) {
                combatEquipInfo.setAfterRiskLevel("3");
            } else if (riskDistance <= 30) {
                combatEquipInfo.setAfterRiskLevel("2");
            } else {
                combatEquipInfo.setAfterRiskLevel("1");
            }
       }
        combatEquipInfoMapper.updateCombatEquipInfo(combatEquipInfo);
        return AjaxResult.success("抗定位后回调成功");
    }

    @Override
    public List<CombatFakeIp> selectCombatFakeIpList(CombatFakeIp combatFakeIp) {
        List<CombatFakeIp> combatFakeIps = combatFakeIpMapper.selectCombatFakeIpList();
        return combatFakeIps;
    }

    @Override
    @Transactional
    public AjaxResult fakeIpAdd(CombatFakeIp combatFakeIp) {
        String fakeIp = combatFakeIp.getFakeIp();
        CombatFakeIp fakeIpInfo = combatFakeIpMapper.selectCombatFakeIpByIp(fakeIp);
        if (fakeIpInfo != null) {
            log.error("虚假IP已存在");
            throw new BaseException("虚假IP已存在");
        }
        try {
            // 获取用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            SysUser user = loginUser.getUser();
            combatFakeIp.setCreateBy(user.getUserName());
            combatFakeIp.setCreateTime(new Date());
            combatFakeIpMapper.insertCombatFakeIp(combatFakeIp);
            return AjaxResult.success("添加成功");
        } catch (Exception e) {
            log.error("添加失败", e);
            throw new BaseException("添加失败");
        }
    }

    @Override
    public AjaxResult fakeIpEdit(CombatFakeIp combatFakeIp) {
        try {
            // 获取用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            SysUser user = loginUser.getUser();
            combatFakeIp.setUpdateBy(user.getUserName());
            combatFakeIp.setUpdateTime(new Date());
            combatFakeIpMapper.updateCombatFakeIp(combatFakeIp);
            return AjaxResult.success("修改成功");
        } catch (Exception e) {
            log.error("修改失败", e);
            throw new BaseException("修改失败");
        }
    }

    @Override
    public AjaxResult fakeIpDel(Long id) {
        if (id == null) {
           throw new BaseException("id不能为空");
        }
        try {
            combatFakeIpMapper.deleteCombatFakeIpById(id);
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            log.error("删除失败", e);
            throw new BaseException("删除失败");
        }
    }

    @Override
    public AjaxResult importEquipInfoData(MultipartFile file, String algorithmMark) {
        // 校验参数
        if (StringUtils.isBlank(algorithmMark)) {
            throw new BaseException("算法标识不能为空");
        }
        List<CombatEquipInfo> equipInfoList = new ArrayList<CombatEquipInfo>();
        try {
            ExcelUtil<CombatEquipInfo> util = new ExcelUtil<CombatEquipInfo>(CombatEquipInfo.class);
            List<CombatEquipInfo> list = util.importExcel(file.getInputStream());
            for (CombatEquipInfo combatEquipInfo : list) {
                if (StringUtils.isBlank(combatEquipInfo.getEquipIp())) {
                    log.info("设备IP为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                // 如果IP不为空，查询设备信息表中是否有这个设备信息
                CombatEquipInfo equipInfo = combatEquipInfoMapper.selectCombatEquipInfoByIp(combatEquipInfo.getEquipIp());
                if (equipInfo != null) {
                    log.info("设备信息已存在，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipname())) {
                    log.info("设备名称为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipOrg())) {
                    log.info("设备所属单位为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipCity())) {
                    log.info("设备城市为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipAddress())) {
                    log.info("设备地址为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipArea())) {
                    log.info("设备区为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipLon())) {
                    log.info("设备经度为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                if (StringUtils.isBlank(combatEquipInfo.getEquipLat())) {
                    log.info("设备纬度为空，{}" + combatEquipInfo.getEquipIp());
                    // 跳过当前设备信息
                    continue;
                }
                equipInfoList.add(combatEquipInfo);
            }

            // 批量插入设备信息
            for (CombatEquipInfo combatEquipInfo : equipInfoList) {
                // 根据定位标识，选择定位算法
                Map<String, Object> map = new HashMap<>(16);
                combatEquipInfo.setAlgorithmMark(algorithmMark);
                if (algorithmMark.equals("1")) {
                    // 1-基于高精度地标的定位方法
                    map = pinpointService.pinpoint(combatEquipInfo.getEquipIp(), combatEquipInfo.getEquipCity(), combatEquipInfo.getEquipLon(), combatEquipInfo.getEquipLat());
                    combatEquipInfo.setBeforeEquipRiskLat(map.get("geo_lat").toString());
                    combatEquipInfo.setBeforeEquipRiskLon(map.get("geo_lon").toString());
                    String error = map.get("error").toString();
                    // 保留两位小数
                    combatEquipInfo.setBeforeRiskDistance(new DecimalFormat("#.00").format(Double.parseDouble(map.get("error").toString())));
                    combatEquipInfo.setRiskMark("1");
                    // 判断设备风险等级，如果风险距离大于等于10小于30，则为中风险，大于30则为低风险，小于10则为高风险
                    if (Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) >= 10 && Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) < 30){
                        combatEquipInfo.setRiskLevel("2");
                    }else if (Double.parseDouble(combatEquipInfo.getBeforeRiskDistance()) < 10){
                        combatEquipInfo.setRiskLevel("3");
                    }else {
                        combatEquipInfo.setRiskLevel("1");
                    }
                } else if (algorithmMark.equals("2")) {
                    // 2-基于时延的定位
                    // 新增基于时延的定位任务
                    CombatEquipRepositingTask combatEquipRepositingTask = new CombatEquipRepositingTask();
                    combatEquipRepositingTask.setProtectedIp(combatEquipInfo.getEquipIp());
                    combatEquipRepositingTask.setStartime(new Date());
                    combatEquipRepositingTask.setTaskState("1");
                    combatEquipRepositingTask.setEquipLat(combatEquipInfo.getEquipLat());
                    combatEquipRepositingTask.setEquipLon(combatEquipInfo.getEquipLon());
                    combatEquipRepositingTaskMapper.insertCombatEquipRepositingTask(combatEquipRepositingTask);
                    pinpointService.pinpointDelay(combatEquipInfo.getId(), combatEquipInfo.getEquipIp(), combatEquipInfo.getEquipCity(), combatEquipInfo.getEquipLon(), combatEquipInfo.getEquipLat());
                }
                combatEquipInfoMapper.insertCombatEquipInfo(combatEquipInfo);
            }
        } catch (Exception e) {
            log.error("导入失败", e);
        }
        return null;
    }

    @Override
    public void repositioning(CombatEquipInfo combatEquipInfo) {
        Long id = combatEquipInfo.getId();
        if (id == null) {
            throw new BaseException("id不能为空");
        }
        CombatEquipInfo equipInfo = combatEquipInfoMapper.selectCombatEquipInfoById(id);

        // 重新定位
        Map<String, Object> map = new HashMap<>(16);
        if (combatEquipInfo.getAlgorithmMark().equals("1")) {
            // 基于高精度地标的定位方法
            map = pinpointService.pinpoint(equipInfo.getEquipIp(), equipInfo.getEquipCity(), equipInfo.getEquipLon(), equipInfo.getEquipLat());
            equipInfo.setBeforeEquipRiskLat(map.get("geo_lat").toString());
            equipInfo.setBeforeEquipRiskLon(map.get("geo_lon").toString());
            String error = map.get("error").toString();
            // error保留两位小数
            equipInfo.setBeforeRiskDistance(new DecimalFormat("#.00").format(Double.parseDouble(error)));
            if ("0".equals(equipInfo.getRiskMark())) {
                equipInfo.setRiskMark("1");
            }
//            equipInfo.setBeforeRiskDistance(map.get("error").toString());
        } else if (combatEquipInfo.getAlgorithmMark().equals("2")) {
            // 基于时延的定位方法
            CombatEquipRepositingTask combatEquipRepositingTask = new CombatEquipRepositingTask();
            combatEquipRepositingTask.setProtectedIp(equipInfo.getEquipIp());
            combatEquipRepositingTask.setStartime(new Date());
            combatEquipRepositingTask.setTaskState("1");
            combatEquipRepositingTask.setEquipLat(equipInfo.getEquipLat());
            combatEquipRepositingTask.setEquipLon(equipInfo.getEquipLon());
            combatEquipRepositingTaskMapper.insertCombatEquipRepositingTask(combatEquipRepositingTask);
            pinpointService.pinpointDelay(combatEquipRepositingTask.getId(), equipInfo.getEquipIp(), equipInfo.getEquipCity(), equipInfo.getEquipLon(), equipInfo.getEquipLat());
        }
         // 定位后风险等级0-10为高风险，10-30为中风险，30以上为低风险
        if (StrUtil.isNotBlank(equipInfo.getBeforeRiskDistance()) && !"2".equals(equipInfo.getRiskMark())) {
            double riskDistance = Double.parseDouble(equipInfo.getBeforeRiskDistance());
            if (riskDistance < 10) {
                equipInfo.setRiskLevel("3");
            } else if (riskDistance >= 10 && riskDistance < 30) {
                equipInfo.setRiskLevel("2");
            } else {
                equipInfo.setRiskLevel("1");
            }
        }
        combatEquipInfoMapper.updateCombatEquipInfo(equipInfo);
    }

    @Override
    public List<RiskDataStatisticsVo> riskDataByPosition() {
        // 获取所有设备信息
        List<CombatEquipInfo> equipInfoList = combatEquipInfoMapper.selectCombatEquipInfoList(new CombatEquipInfo());
        if (equipInfoList == null || equipInfoList.isEmpty()) {
            return null;
        }

        // 对城市分类
        Map<String, List<CombatEquipInfo>> cityMap = equipInfoList.stream().collect(Collectors.groupingBy(CombatEquipInfo::getEquipCity));

        // 对城市分类中，高，低风险
        Set<Map.Entry<String, List<CombatEquipInfo>>> entries = cityMap.entrySet();
        List<RiskDataStatisticsVo> list = new ArrayList<>();
        // 遍历数据
        for (Map.Entry<String, List<CombatEquipInfo>> entry : entries) {
            String city = entry.getKey();
            List<CombatEquipInfo> value = entry.getValue();

            RiskDataStatisticsVo vo = new RiskDataStatisticsVo();
            int lowRiskCount = 0;
            int mediumRiskCount = 0;
            int highRiskCount = 0;

            for (CombatEquipInfo equipInfo : value) {
                String riskLevel = equipInfo.getRiskLevel();
                if ("1".equals(riskLevel)) {
                    lowRiskCount++;
                } else if ("2".equals(riskLevel)) {
                    mediumRiskCount++;
                } else if ("3".equals(riskLevel)) {
                    highRiskCount++;
                }
            }

            vo.setLowRiskCount(lowRiskCount);
            vo.setMediumRiskCount(mediumRiskCount);
            vo.setHighRiskCount(highRiskCount);
            vo.setCity(city);
            list.add(vo);
        }
        return list;
    }
}
